- /* sdfddsub.cpp by K.Tsuru */
- // function ID = 322 DRADIX
- #ifndef SN_H
- #include "sn.h"
- #endif
- /**********************************************************************
- SDouble class
- m - n, same sign and |m|>=|n|.
- d = m.rdxExp - n.rdxExp
- Adjustment figures.
- d >= 0
- m = v[0].0..0v[mT]....v[mH] * R^(e+d) 0.001234 ^ 10^(5+2)
- n = v[0].0..0v[nT]....v[nH] * R^e 0.000456789 ^ 10^5
- = 0.00...v[d+nT]....v[d+nH] * R^(e+d) 0.00000456789^ 10^(5+2)
- In the fixed point mode it is possible that d < 0.
- m = v[0].0..0v[mT]....v[mH] * R^(e+d) 0.1234 ^ 10^(5-2)
- n = v[0].0..0v[nT]....v[nH] * R^e 0.000456789 ^ 10^5
- = 0.00...v[d+nT]....v[d+nH] * R^(e+d) 0.0456789^ 10^(5-2)
- It satisfies mT>= d+nT > 0.
- ************************************************************************/
- static const char* func = "DDSub"; // add "const" since version 2.192
-
- SDouble DDSub(const SDouble& m, const SDouble& n){
- //SDouble only
- if((m.Type() != m.REAL)||(n.Type() != n.REAL)) m.SetError(m.RADIX_ERR, func, 322);
- if(m.Sign(322) == 0) return -n;
- if(n.Sign(322) == 0) return m;
- //check sign
- if( m.Sign() != n.Sign() ) m.SetError(m.SYNTAX_ERR, func, 322);
-
- //check |m| >> |n|
- //"long" type is necessary in the 16 bits system.
- long max_fig = (long)m.CurrentMaxSize() -1;
- long di = m.NetRdxExp() - n.NetRdxExp();
- if( di >= max_fig) return m; // m >> n
-
- int de = m.rdxExp - n.rdxExp; //possible de < 0
- SDouble result, N;
- const fType* Mf = m.ReadFigures();
- const fType* Nf;
- uint ml = m.Last(), mf = m.First(), nl, nf;
- // step 1 : adjustment of figures
- if(de){
- N = n; //make copy of n
- N.ShiftArray(de);//For de > 0 the size is expanded if necessary.
- //If de < 0 and it exceeds the boundary, an overflow error occures.
- //This is a syntax error.If |m| > |n| it does not occure.
- N.rdxExp += de; //exponent value is used in Sign() bellow
- //If N.sign != 0 and the non-zero part is out of range, Sign() returns zero.
- if(N.Sign(322) == 0) return m; //check n << m again
- Nf = N.ReadFigures(); nl = N.Last(); nf = N.First();
- } else{
- Nf = n.ReadFigures(); nl = n.Last(); nf = n.First();
- }
- // step 2 : compare figures
- int i, k = 0, top = 0, btm;
- if(ml < nl){ //m=0.1, n=0.0823, n has larger
- k = -1; btm = (int)nl; top = (int)ml;
- } else if(ml > nl){
- k = 1; btm = (int)ml; top = (int)nl;
- } else btm = (int)ml; //same, in step 3 do not use "top"
-
- uint rsize = (uint)btm+1;
- result.valloc(rsize , -1); //does not initialize
- result.figure.clear( uint(btm+1) ); //initialize lower part
- fType* rf = result.figure.Elements();
- #ifndef NDEBUG
- result.figure(btm); if(k) assert(btm >= top); // error check
- #endif
- // step 3 : processing lower part in the case of diffrent figures
- // top btm
- if(k == -1){ // 0.aaaa bbbb .... 0000 - 0.xxxx yyyy .... zzzz
- #ifndef NDEBUG
- if(de) N.figure(btm);
- #endif
- rf[btm] = DRADIX - Nf[btm]; //lowest figure : 10000 - Nf[btm]
- fType r1 = DRADIX-1;
- for(i = btm-1; i > top; i--) rf[i] = r1 - Nf[i]; // 9999 - Nf[i]
- //k has an information of borrowing, then does not let k = 0.
- //Here i = top.
- // btm top
- } else if(k == 1){ //0.aaaa bbbb... cccc - 0.xxxx yyyy 0000 .... 0000
- //Copy lower part of m to that of result.
- #ifndef NDEBUG
- m.figure(btm); // error check
- #endif
- memcpy(rf+top+1, Mf+top+1, (btm-top)*sizeof(fType));
- // for(i = btm; i > top; i--) rf[i] = Mf[i]; // N[i] = 0
- i = top; k = 0;
- } else i = btm; // k = 0, m and n(or N) have same figures.
-
- // step 4 : It begins subtraction.
- top = (int)min(mf, nf);
- #ifndef NDEBUG
- m.figure(i);
- if(N.RawSign() != m.UNDECIDED) N.figure(i); // error check
- #endif
- int w;
- for( ; i >= top; i--){
- w = (int)Mf[i] - (int)Nf[i] + k;
- // -DRADIX <= w < DRADIX : 16 bits, int type is Ok.
- if(w < 0) {
- k = -1; w += DRADIX; //borrowing
- } else k = 0;
- rf[i] = (fType)w;
- }
- if(top) result.figure.clear(0, uint(top - 1) ); //clear upper part by zero
- //If m > n the borrowing k must be equal to zero.
- if(k) m.SetError(m.SYNTAX_ERR, "m < n in DDSub", 36);
- // step 5 : check the position
- while(!rf[top]) top++;
- result.aTail = (uint)top;
-
- btm = max((int)ml, (int)nl);
- while(!rf[btm]) btm--;
- result.aHead = (uint)btm;
- //Set sign and exponent.
- result.SetSign( m.Sign() ); result.rdxExp = m.rdxExp;
- result.Reform(322); //Processing DoCutDown() etc.
- return result;
- }
sdfddsub.cpp : last modifiled at 2017/03/13 14:31:58(4,522 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).